package com.nuanshui.heatedloan.service.cms.security;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.nuanshui.heatedloan.constant.TransactionManagerType;
import com.nuanshui.heatedloan.dao.cms.security.ModuleDao;
import com.nuanshui.heatedloan.entity.cms.security.Module;
import com.nuanshui.heatedloan.service.cms.BaseService;
import com.nuanshui.heatedloan.service.cms.ServiceException;
import com.nuanshui.heatedloan.util.dwz.DwzPage;
import com.nuanshui.heatedloan.util.springdata.PageUtils;

/**
 * 模块管理的服务类
 * 
 */
@Service
@Transactional(readOnly = true,value=TransactionManagerType.MANAGER_SERVICE_TRANSACTION_MARGER)
public class ModuleService extends BaseService<Module, Long> {

	@Autowired
	private ModuleDao moduleDao;

	/**
	 * 删除模块
	 */
	@Override
	@Transactional(value=TransactionManagerType.MANAGER_SERVICE_TRANSACTION_MARGER)
	public void delete(final Long id)  {
		

		final Module module = moduleDao.findOne(id);

		// 先判断是否存在子模块，如果存在子模块，则不允许删除
		if (module.getChildren().size() > 0) {
			throw new ServiceException(module.getName() + "模块下存在子模块，不允许删除。");
		}

		moduleDao.delete(module);
	}

	/**
	 * 根据parentId分页
	 */
	public List<Module> find(final Long parentId, final DwzPage page) {
		final org.springframework.data.domain.Page<Module> p = moduleDao
				.findByParentId(parentId, PageUtils.createPageable(page));
		PageUtils.injectPageProperties(page, p);
		return p.getContent();
	}

	/**
	 * 根据名称查询
	 */
	public List<Module> find(final Long parentId, final String name,
			final DwzPage page) {
		final org.springframework.data.domain.Page<Module> p = moduleDao
				.findByParentIdAndNameContaining(parentId, name,
						PageUtils.createPageable(page));
		PageUtils.injectPageProperties(page, p);
		return p.getContent();
	}

	/**
	 * 判断是否是根模块.
	 */
	private boolean isRoot(final Long id) {
		return id == 1;
	}

	/**
	 * 拿到所有模块
	 * 
	 * @return 返回最上层的父亲，可以根据最上层的模块，拿到下面的Children
	 */
	public Module getTree() {
		// 拿到所有的人，先从缓存中取
		final List<Module> list = moduleDao.findAllWithCache();
		final List<Module> rootList = makeTree(list);

		return rootList.get(0);
	}
	
	public List<Module> getApiTree(){
		final List<Module> list = moduleDao.findAllWithCache();
		return list;
	}

	/**
	 * 返回最上层的根节点，可以根据这个根节点找到下面的孩子
	 * 
	 * @param list
	 * @return 返回根节点，也就是parent_id为空的模块
	 */
	private List<Module> makeTree(final List<Module> list) {
		final List<Module> parent = new ArrayList<Module>();
		// 找到根模块
		for (final Module e : list) {
			if (e.getParent() == null) {
				e.setChildren(new ArrayList<Module>(0));
				parent.add(e);
			}
		}
		// 删除parentId = null;
		list.removeAll(parent);

		// 从根节点开始找孩子
		makeChildren(parent, list);

		return parent;
	}

	/**
	 * 递归，帮助父亲找孩子
	 * 
	 * @param parent
	 *            最上层的父亲
	 * @param children
	 *            所有没有找到爹的孩子
	 */
	private void makeChildren(final List<Module> parent,
			final List<Module> children) {
		// 所有的list都删除了，也就是所有的孩子都找到爹了，递归结束
		if (children.isEmpty()) {
			return;
		}
		// 用于存放已经找到父亲的孩子
		final List<Module> tmp = new ArrayList<Module>();
		// 遍历所有父亲
		for (final Module c1 : parent) {
			// 遍历所有的孩子，看看是不是这个父亲的孩子
			for (final Module c2 : children) {
				c2.setChildren(new ArrayList<Module>(0));
				if (c1.getId().equals(c2.getParent().getId())) {// 找到了孩子
					// 把这个孩子加到父亲的list中
					c1.getChildren().add(c2);
					// 把孩子放到tmp中
					tmp.add(c2);
				}
			}
		}
		// 把已经找到父亲的孩子删掉
		children.removeAll(tmp);
		// 对于下一次递归来说，应该从已经找到父亲的孩子开始，帮助已经已经找到父亲的孩子找孩子
		makeChildren(tmp, children);
	}

}
